﻿using System;
using System.Collections.Generic;
using System.Text;
using BaseSet.Entity.Common.Text;

namespace BaseSet.Entity.Common.DataOperation
{
    /// <summary>
    /// 扩展字段映射
    /// </summary>
    public class ExpandMaps<T>
    {
        private Dictionary<string, IList<Object>> maps;
        /// <summary>
        /// 
        /// </summary>
        public Dictionary<string, IList<Object>> Maps
        {
            get { return maps; }
            set { maps = value; }
        }

        public ExpandMaps()
        {
            this.maps = new Dictionary<string, IList<object>>();
        }

        /// <summary>
        /// 获取源中指定字段在结果中映射字段的值列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="R"></typeparam>
        /// <param name="sourceList"></param>
        /// <param name="mapFields"></param>
        /// <param name="resultList"></param>
        /// <param name="mapFieldr"></param>
        /// <param name="resultField"></param>
        /// <returns></returns>
        private IList<object> GetMapFieldList<R>(IList<T> sourceList, string mapFields, IList<R> resultList, string mapFieldr, string resultField)
        {
            if (sourceList == null ||
                sourceList.Count == 0 ||
                string.IsNullOrEmpty(mapFields) ||
                resultList == null ||
                resultList.Count == 0 ||
                string.IsNullOrEmpty(mapFieldr) ||
                string.IsNullOrEmpty(resultField))
            {
                return null;
            }

            if (sourceList[0].GetType().GetProperty(mapFields) == null ||
                resultList[0].GetType().GetProperty(mapFieldr) == null ||
                resultList[0].GetType().GetProperty(resultField) == null)
            {
                //没有该字段
                return null;
            }

            Dictionary<string, object> dic = GetDictionary<R>(resultList, mapFieldr, resultField);

            IList<object> result = new List<object>();
            object obj;
            string curKey = string.Empty;
            for (int i = 0; i < sourceList.Count; i++)
            {
                curKey = Tools.GetPropertyValue(sourceList[i], mapFields) + "";

                if (dic.ContainsKey(curKey))
                {
                    obj = dic[curKey];
                }
                else
                {
                    obj = new object();
                }

                result.Add(obj);
            }

            return result;
        }

        /// <summary>
        /// 将数据源的两列构造为字典
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="keyField">源中表示键的字段</param>
        /// <param name="valueField">源中表示值的字段</param>
        /// <returns></returns>
        private Dictionary<string, object> GetDictionary<R>(IList<R> list, string keyField, string valueField)
        {
            if (list == null || list.Count == 0 || string.IsNullOrEmpty(keyField) || string.IsNullOrEmpty(valueField))
            {
                return null;
            }

            if (list[0].GetType().GetProperty(keyField) == null)
            {
                //list中没有这个字段
                return null;
            }

            Dictionary<string, object> result = new Dictionary<string, object>();
            string curKey = string.Empty;
            object curValue = new object();
            for (int i = 0; i < list.Count; i++)
            {
                curKey = Tools.GetPropertyValue(list[i], keyField) + "";
                if (string.IsNullOrEmpty(curKey.Trim()))
                {
                    //键不能空
                    continue;
                }
                curValue = Tools.GetPropertyValue(list[i], valueField);
                result.Add(curKey, curValue);
            }

            return result;
        }

        /// <summary>
        /// 将源类型在目标类型中的映射结果增加至映射集中
        /// </summary>
        /// <typeparam name="T">源类型</typeparam>
        /// <typeparam name="R">目标类型</typeparam>
        /// <param name="sourceList">源数据</param>
        /// <param name="mapFields">源映射字段</param>
        /// <param name="resultList">目标数据</param>
        /// <param name="mapFieldr">目标映射字段</param>
        /// <param name="resultField">目标字段</param>
        public void AddMap<R>(IList<T> sourceList, string mapFields, IList<R> resultList, string mapFieldr, string resultField)
        {
            IList<object> lst = GetMapFieldList<R>(sourceList, mapFields, resultList, mapFieldr, resultField);
            this.maps.Add(resultField, lst);
        }
    }
}
